#include <pthread.h>
#include <sys/types.h>
#include <sys/sem.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/shm.h>


int a = 0;

int i = 0;

int semid;	//定义信号量标识



void P(int semid,int index){
	struct sembuf sem;       // 对指定的信号量进行p操作
	sem.sem_num = index;
	sem.sem_op = -1;
	sem.sem_flg = 0;
	semop(semid,&sem,1);	
	return;
}


void V(int semid,int index){
	struct sembuf sem;       // 对指定的信号量进行V操作
	sem.sem_num = index;
	sem.sem_op = 1;
	sem.sem_flg = 0;
	semop(semid,&sem,1);	
	return;
}

//calculate thread
void* subp1(void* arg){
	while(1){
		P(semid,0);
		i++; a=a+i;
                if(i==101){
                  V(semid,1);
                  V(semid,2);
                  return NULL;
                 }
		else if(a%2!=0)//odd
                       V(semid,1);
                     else 
                       V(semid,2);
                }
}



void* subp2(void* arg){//print odd numbers
	while(1){
		P(semid,1);
                  if(i==101) return NULL;
		printf("Odd  thread: The sum is %d.\n",a);
		V(semid,0);
}

	return NULL;
}




void* subp3(void* arg){//print even numbers
	while(1){
		P(semid,2);
                  if(i==101) return NULL;
		printf("Even thread: The sum is %d.\n",a);
		V(semid,0);
          
}

	return NULL;
}

int main(){
	semid = semget(IPC_PRIVATE,3,IPC_CREAT|0666);
	semctl(semid,0,SETVAL,1);	//计算线程信号量
	semctl(semid,1,SETVAL,0);	//打印奇数线程信号量  
	semctl(semid,2,SETVAL,0);	//打印偶数线程信号量
	pthread_t p1,p2,p3;
	int ret1,ret2,ret3;
	
	ret1=pthread_create(&p1,NULL,subp1,NULL);
	if(ret1!=0){
		printf("Create pthread1 error!\n");
		exit(1);
	}
		
	ret2=pthread_create(&p2,NULL,subp2,NULL);
	if(ret2!=0){
		printf("Create pthread2 error!\n");
		exit(1);
	}

	ret3=pthread_create(&p3,NULL,subp3,NULL);
	if(ret3!=0){
		printf("Create pthread3 error!\n");
		exit(1);
	}
	pthread_join(p1,NULL);
	pthread_join(p2,NULL);
	pthread_join(p3,NULL);	
	printf("All threads is over.\n ");
	return 0;
}


